﻿using System;
namespace Game
{
    public class Position
    {
        public Position(int x = -1, int y = -1)
        {
            X = x;
            Y = y;
        }
        public int X { get; set; }
        public int Y { get; set; }
    }
    abstract public class Slime
    {
        protected int _id;
        protected char _side;

        protected int _atk;
        protected int _rag;
        protected int _movdis;
        protected int _level;
        protected int _exp;
        protected bool _hited;
        protected bool _canmove; /*表示單位是否移動*/
        public Slime Clone()
        {
            return (Slime)this.MemberwiseClone();
        }
        public int MovDis
        {
            get { return _movdis; }
            set { _movdis = value; }
        }
        public char Side
        {
            get { return _side; }

        }
        public bool CanMove
        {
            get { return _canmove; }
        }

        public bool Hited
        {
            get { return _hited; }
            set { _hited = value; }
        }

        public bool Active { get; set; } /*表示單位是否攻擊*/

        public int Cost
        {
            get { return MaxHP + _atk + _rag * 10 + _movdis * 10; }
        }
        public int ID
        {
            get { return _id; }
        }
        public int Range
        {
            get { return _rag; }
        }
        public int X { get; set; }
        public int Y { get; set; }
        public Position Pos
        {
            get { return new Position(X, Y); }
            set { X = value.X; Y = value.Y; }
        }

        public int HP { get; set; }
        public int MaxHP { get; set; }
        public string Type { get; set; }

        public char Icon
        {
            get { return (char)(_id + _side); }
        }
        public int ATK {
            get { return _atk;}
        }

        public Slime(char side, int id, int x, int y)
        {
            _id = id;
            _side = side;
            _level = 1;
            _exp = 0;
            X = x;
            Y = y;
            Active = false; /*初始為不可攻擊*/
            _canmove = false; /*初始為不可移動*/
            Type = InitType();
        }       

        public void Levelup()
        {
            _level++;
            HP += (int)(0.1 * _level * MaxHP);
            MaxHP += (int)(0.1 * _level * MaxHP);
            _atk += (int)(0.1 * _level * _atk);
            //HP = _maxhp;
        } /* 升級 HP是否補滿及升級函式之後決定 */


        public void Move(int x, int y)
        {
            Position P = new Position(x, y);
            Move(P);
        }/* 移動到(x,y) */

        public void Move(Position P)
        {
            if (_canmove && (Math.Abs(P.X - X) + Math.Abs(P.Y - Y)) <= _movdis)
            {
                X = P.X;
                Y = P.Y;
                _canmove = false;
            }
        }/* 移動到(x,y) */


        public void Status()
        {
            System.Console.WriteLine("hp = {0}/{1}", HP, MaxHP);
            System.Console.WriteLine("atk = {0}", _atk);
            System.Console.WriteLine("rag = {0}", _rag);
            System.Console.WriteLine("mov = {0}", _movdis);
            System.Console.WriteLine("level = {0}", _level);
            System.Console.WriteLine("exp = {0}/{1}", _exp, _level * _level);

            System.Console.WriteLine("state = {0} ,Can Move = {1}",
                Active ? "Active" : "Unactive", _canmove ? "Y" : "N");
        }/*顯示史萊姆狀態*/

        public void Attack(Slime target)
        {
            if (Active &&
                Math.Abs(target.X - X) + Math.Abs(target.Y - Y) <= _rag &&
                target.HP > 0 && this.HP > 0 && _side!= target._side)
            {
                target.Hited = true;
                target.HP -= _atk;
                Console.WriteLine(Icon + "傷害" + target.Icon + " " + _atk + " (" + target.HP + "/" + target.MaxHP + ")");
                if (target.HP <= 0)
                {
                    _exp += target._level;
                    while (_exp >= _level * _level)
                    { Levelup(); }
                }
                Active = false;

                //Console.ReadLine();
            }
            
        }

        public void MaAtk(Slime target)
        {
            if (Active &&
                Math.Abs(target.X - X) + Math.Abs(target.Y - Y) <= _rag &&
                target.HP > 0 && this.HP > 0 && _side != target._side)
            {
                target.Hited = true;
                target.HP -= _atk;
                if (target.HP <= 0)
                {
                    _exp += target._level;
                    while (_exp >= _level * _level)
                    { Levelup(); }
                }
                Active = false;

                //Console.ReadLine();
            }

        }


        public void Stay()
        {
            if (Active && HP > 0 && !Hited)
            {
                HP += (int)(MaxHP * 0.1);
                
                //HP += 100; // 100  = 2 * 50 是小兵*2的傷害
                if (HP > MaxHP)
                { HP = MaxHP; }    

                Active = false;
            }
        }/*非攻擊後結束動作可回HP*/

        public void WakeUp()
        {
            Active = true;
            _canmove = true;
        }

        public bool IsDead() {
            return HP <= 0;
        }

        abstract public void Display(char C);
        abstract public string InitType();
    }
}